package com.mdp.im.core.subscriber.action;

import com.alibaba.fastjson.JSONObject;
import com.mdp.im.core.socket.ChannelsHolder;
import com.mdp.im.core.utils.msg.Action;
import com.mdp.im.core.utils.msg.MsgState;
import io.netty.channel.Channel;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.ChannelMatcher;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 消息处理抽象类
 * 
 * @author chenyc
 * @date 2018/5/15
 */
public class AbstractSubscriberAction {
    

    
    /**
     * 处理消息
     * @param includeMe 返回消息是否也包括我自己
     * @param groupIds 需要推送消息的群组列表
     * @param userids 需要推送消息的用户列表
     * @param message
     * @return 
     */
    public Long handleMessageWithGroups(JSONObject message,boolean includeMe,String[] groupIds,String ...userids) {
    	String channelId=message.getString("channelId");
    	message.remove("channelId");
    	String sendUserid=message.getString("sendUserid");
    	String strMessage=message.toJSONString();
    	message.put("channelId", channelId);
        long sendCount=0;
        Map<String,Long> map=new HashMap<>();
        map.put("count", (long) 0);
        if (userids != null) {
            for (String user : userids) {

                if (user != null && !user.trim().isEmpty()) {
                	if(includeMe==false) {
                	     if(user.equals(sendUserid)) {
                	    	 continue;
                	     }
                	}
                    Set<String> chIdSet = ChannelsHolder.getChannelIdsByUserid(user);
                    if (chIdSet == null) {
                        continue;
                    }
                    for (String channelId2 :chIdSet) {
                        Channel ch = ChannelsHolder.getChannelById(channelId2);
                        if (ch != null) {
                        	sendCount=sendCount+1;
                            ch.writeAndFlush(new TextWebSocketFrame(strMessage));
                        }
                    }
                }
            }
        }
        if (groupIds != null) {
            for (String group : groupIds) {
                if (group != null && !group.trim().isEmpty()) {
                    ChannelGroup cg = ChannelsHolder.getChannelGroups().get(group);
                    if(cg != null) {
                    	if(includeMe==false) {
							cg.writeAndFlush(new TextWebSocketFrame(strMessage),new ChannelMatcher( ) {
    							public Long count=(long) 0;
    							@Override
    							public boolean matches(Channel channel) {
    								// TODO Auto-generated method stub
    								if(!channel.id().asLongText().equalsIgnoreCase(channelId)) { 
    									count=count+1;
    									map.put("count", count);
    									return true;
    								}else {
    									return false;
    								} 
    							}
    						});
                    	}else {
                    		sendCount=sendCount+1;
                    		cg.writeAndFlush(new TextWebSocketFrame(strMessage));
                    	}
                        
                    }
                }
            }
        }
        Long sendCount2=sendCount+map.get("count");
        return sendCount2;
    }

    /**
     * 处理消息
     * @param includeMe 返回消息是否也包括我自己
     * @param groupId 需要推送消息的群组
     * @param userids 需要推送消息的用户列表
     * @param message
     */
    public Long handleMessageWithGroup(JSONObject message,boolean includeMe,String groupId,String ...userids) { 
    	if(StringUtils.isEmpty(groupId)) {
    		return this.handleMessageWithGroups(message, includeMe, (String[])null, userids);
    	}else {
    		String[] groupIds=new String[1];
    		groupIds[0]=groupId;
    		return this.handleMessageWithGroups(message, includeMe, groupIds, userids);
    	}
    	
    }
    /**
     * 处理消息 
     * @param userids 需要推送消息的用户列表
     * @param message
     */
    public Long handleMessageWithUserids(JSONObject message,String ...userids) { 
    	return handleMessageWithGroup(message,true,null,userids);
    	
    }
    
    /**
     * 处理消息
     * @param includeMe 返回消息是否也包括我自己
     * @param message
     */
    public Long handleMessageWithDefaultGroup(JSONObject message,boolean includeMe) {
        long sendCount=0;
        Map<String,Long> map=new HashMap<>();
        map.put("count", (long) 0);
    	String strMessage=message.toJSONString(); 
    	String channelId=message.getString("channelId");
        ChannelGroup cg = ChannelsHolder.getDefaultGroup();
        if(cg != null) {
        	if(includeMe==false) {
        		cg.writeAndFlush(new TextWebSocketFrame(strMessage),new ChannelMatcher() { 
					@Override
					public boolean matches(Channel channel) {
						return !channel.id().asLongText().equalsIgnoreCase(channelId);
					}
				});
                sendCount=cg.size();
        	}else {
        		cg.writeAndFlush(new TextWebSocketFrame(strMessage));
                sendCount=cg.size()-1;
        	}
        }
        return sendCount;
    }
    /**
     * 处理消息回执
     * { 
     *   data:{
     *   	msgId:'',
     *      groupId:''
     *   }
     * 	 tips:{
     * 	 	isOk:true|false,
     * 		tipscode:'send|reach|read|back',
     * 	    msg:'send-已发送，reach-已送达，read-已读，back-已回撤'
     *   }
     * }
     * @param channelId 发送人会话编号
     * @param message
     */
    public void handleMessageReceipt(JSONObject message,String channelId) {
    	
    	String strMessage=message.toJSONString();   
    	Channel c=ChannelsHolder.getChannelById(channelId);
    	if(c==null) {
    		return;
    	}
    	c.writeAndFlush(new TextWebSocketFrame(strMessage));
         
    }
    /**
     * 
     * @param groupId
     * @param sourceMsgId
     * @param msgId
     * @param msgType
     * @param tipscode
     * @return
     */
    public JSONObject getMessageReceipt(String groupId,String sendUserid,String toUserid,String sourceMsgId,String msgId,String msgType,String tipscode) {
        JSONObject messageReceipt=new JSONObject();
        messageReceipt.put("action", Action.MESSAGE_STATE_REPORT);
        messageReceipt.put("msgId", msgId); 
        messageReceipt.put("sendUserid", sendUserid); 
        messageReceipt.put("toUserid", toUserid); 
        messageReceipt.put("groupId", groupId);
        messageReceipt.put("sourceMsgId", sourceMsgId);  
        messageReceipt.put("msgType", msgType); 
        messageReceipt.put("msgState", tipscode);
        messageReceipt.put("msgStateDesc", MsgState.getTipsMsg(tipscode));
        return messageReceipt;
    }

}
